﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Security.Principal;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.SignalR;
namespace IM
{
    /// <summary>
    /// 即使通信服务(可供客户端调用的方法开头用小写)
    /// </summary>
    public class ChatsHub : Hub
    {
        private static readonly ConcurrentDictionary<string, string> clientIdMap =
           new ConcurrentDictionary<string, string>();

        #region 重载Hub方法
        /// <summary>
        /// 建立连接
        /// </summary>
        /// <returns></returns>
        public override async Task OnConnectedAsync()
        {
            var name = Context.GetHttpContext().Request.Query["name"];
            await Clients.All.SendAsync("SendAll", $"{name} joined the chat");

            await base.OnConnectedAsync();
        }
        /// <summary>
        /// 断开连接
        /// </summary>
        /// <param name="exception">异常信息</param>
        /// <returns></returns>
        public override async Task OnDisconnectedAsync(Exception exception)
        {
            await RemoveOnline();
            await base.OnDisconnectedAsync(exception);
        }

        #endregion

        #region 客户端操作
        /// <summary>
        /// 移除在线用户
        /// </summary>
        public async Task RemoveOnline()
        {
            string clientId = Context.ConnectionId;
            clientIdMap.TryGetValue(clientId, out string userId);
            await Groups.RemoveFromGroupAsync(clientId, userId);
        }
        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="myUserId">我的UserId</param>
        /// <param name="toUserId">对方UserId</param>
        /// <param name="msg">消息</param>
        /// <param name="isSystem">是否系统消息0不是1是</param>
        public async Task SendMsg(string myUserId, string toUserId, string msg, int isSystem)
        {
            await Clients.Group(toUserId).SendAsync("RevMsg",myUserId, msg, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), isSystem);
        }
        public Task SendAll(string name, string message)
        {
            return Clients.All.SendAsync("SendAll", $"{name}: {message}");
        }
        public async Task SendInfo(string userId)
        {
            string clientId = Context.ConnectionId;
            clientIdMap.GetOrAdd(clientId, userId);
            await Groups.AddToGroupAsync(clientId, userId);
        }
        #endregion

        #region MyRegion

        /// <summary>
        /// 用户信息
        /// </summary>
        public IPrincipal ClientContextUser
        {
            get { return Context.User; }
        }
        #endregion
    }
}
